package com.mlink.ai.chat.ui.activity.chat

import android.content.Context
import android.content.Intent
import android.net.Uri
import android.os.Build
import android.text.TextUtils
import android.util.Log
import android.widget.TextView
import android.widget.Toast
import androidx.activity.viewModels
import androidx.core.content.FileProvider
import androidx.core.view.isVisible
import androidx.core.widget.addTextChangedListener
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.LinearLayoutManager
import com.google.gson.Gson
import com.mlink.ai.chat.assistant.robot.R
import com.mlink.ai.chat.assistant.robot.databinding.ActivityChatNewBinding
import com.mlink.ai.chat.constants.MYSELF_URL_IN_GOOGLE_PLAY
import com.mlink.ai.chat.local.entity.ChatMessageEntity
import com.mlink.ai.chat.network.bean.response.GetAnswerResponse
import com.mlink.ai.chat.ui.activity.BaseActivity
import com.mlink.ai.chat.ui.adapter.ChatItem
import com.mlink.ai.chat.ui.adapter.ChatType
import com.mlink.ai.chat.ui.fragment.SelectShareBottomDialogFragment
import com.mlink.ai.chat.ui.viewmodel.RecentViewModel
import com.mlink.ai.chat.utils.BitmapUtils
import com.mlink.ai.chat.utils.FileUtils
import com.mlink.ai.chat.utils.LanguageUtils
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.io.File
import java.text.SimpleDateFormat
import java.util.*
import kotlin.math.min

class ChatNewActivity : BaseActivity<ActivityChatNewBinding>() {
    val chatViewModelNew: ChatViewModelNew by viewModels()
    private val recentViewModel: RecentViewModel by viewModels()
    var chatItemList = mutableListOf<ChatItemBean>()
    private var isOpen = false
    private var chatContent = StringBuffer()
    lateinit var chatAdapter: ChatAdapter
    private var isLoading = false
    private var isHandleShare = false
    private var selectShareFragment: SelectShareBottomDialogFragment? = null

    companion object {
        fun startAction(context: Context) {
            context.startActivity(Intent(context, ChatNewActivity::class.java))
        }
    }

    override fun getViewBinding(): ActivityChatNewBinding {
        return ActivityChatNewBinding.inflate(layoutInflater)
    }

    override fun initViews() {
        binding.ivClose.setOnClickListener { finish() }

        binding.ivClear.setOnClickListener {
            binding.etSendMsg.text = null
        }
        binding.ivSendMsg.setOnClickListener {
            if (TextUtils.isEmpty(binding.etSendMsg.text)) {
                return@setOnClickListener
            }
            val chatItemBean = ChatItemBean(ITEM_TYPE_QUESTION, binding.etSendMsg.text.toString())
            chatItemList.add(chatItemBean)
            chatAdapter.notifyDataSetChanged()
            chatViewModelNew.getAnswer2("user", binding.etSendMsg.text.toString())
        }

        binding.etSendMsg.addTextChangedListener {
            binding.ivClear.isVisible = it?.isNotEmpty() == true
            if (it == null || it.trim().isEmpty()) {
                binding.ivSendMsg.isEnabled = false
            } else {
                if (!isLoading) {
                    binding.ivSendMsg.isEnabled = true
                }
            }
        }

        binding.ivRefresh.setOnClickListener {
            recentViewModel.insertHistoryMessage(getHistoryEntity())
//            if (TextUtils.isEmpty(binding.etSendMsg.text)) {
//                return@setOnClickListener
//            }
//            chatViewModelNew.getAnswer2("user", binding.etSendMsg.text.toString())
        }
        binding.ivShare.setOnClickListener {
            selectShareFragment = SelectShareBottomDialogFragment()
            selectShareFragment?.listener =
                object : SelectShareBottomDialogFragment.OnFunctionListener {
                    override fun onTxtClick() {
                        val data = chatAdapter.dataList
                        val builder = StringBuilder()
                        data.forEach {
                            if (it.itemType == ITEM_TYPE_QUESTION) {
                                val content = it.itemText
                                builder.append("Q: $content")
                                builder.append("\n\n")
                            } else if (it.itemType == ITEM_TYPE_ANSWER && !isLoading) {
                                val content = it.itemText
                                builder.append("A: $content")
                                builder.append("\n\n")
                            }
                        }
                        builder.append("${getString(R.string.share_prefix)} $MYSELF_URL_IN_GOOGLE_PLAY")
                        val result = builder.toString()
                        try {
                            val intent = Intent()
                            intent.action = Intent.ACTION_SEND
                            intent.putExtra(Intent.EXTRA_TEXT, result)
                            intent.type = "text/plain"
                            startActivity(Intent.createChooser(intent, "Share to"))
                        } catch (_: Exception) {
                            // do nothing now
                        }
                        selectShareFragment?.dismissAllowingStateLoss()
                    }

                    override fun onPhotoClick() {
                        doShareChat()
                        selectShareFragment?.dismissAllowingStateLoss()
                    }

                }
            selectShareFragment?.show(supportFragmentManager, "")
        }
        initAdapter()
        initObserver()
        binding.etSendMsg.text = null
    }

    private fun doShareChat() {
        if (isHandleShare) {
            return
        }
        isHandleShare = true
        lifecycleScope.launch {
            var uri: Uri
            val bitmap = BitmapUtils.shotRecyclerView(binding.rvChatList)
            if (bitmap == null) {
                isHandleShare = false
                return@launch
            }
            withContext(Dispatchers.IO) {
                val dir = File(FileUtils.getCacheDir(this@ChatNewActivity), "pic")
                val file = File(dir, "share.jpeg")
                if (!dir.exists()) {
                    dir.mkdirs()
                }
                if (!file.exists() && dir.isFile) {
                    file.createNewFile()
                }
                BitmapUtils.bitmapToFile(bitmap, file)
                uri = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                    FileProvider.getUriForFile(
                        this@ChatNewActivity,
                        "$packageName.fileprovider",
                        file
                    )
                } else {
                    Uri.fromFile(file)
                }

            }
            try {
                val intent = Intent()
                intent.action = Intent.ACTION_SEND
                intent.putExtra(Intent.EXTRA_STREAM, uri)
                intent.type = "image/*"
                startActivity(Intent.createChooser(intent, "Share to"))
            } catch (_: Exception) {
                // do nothing now
            } finally {
                delay(1500L) //延时保证选择应用底部弹窗完全获取焦点
                isHandleShare = false
            }
        }
    }


    fun initObserver() {
        chatViewModelNew.isOpenData.observe(this) {
            isOpen = it
            if (isOpen) {
                chatContent = StringBuffer()
            }
        }

        chatViewModelNew.isLoading.observe(this) {
            isLoading = it
            if (it) {
                addLoadingItem()
                return@observe
            }
            removeLoadingItem()

        }
        chatViewModelNew.errorMsgData.observe(this) {
            addErrorItem(it)
        }

        chatViewModelNew.chatReceiveData.observe(this) {
            if (isOpen) {
                if (TextUtils.isEmpty(chatContent)) {
                    chatContent.append(it)
                    val chatItem = ChatItemBean(ITEM_TYPE_ANSWER, chatContent.toString())
                    chatItemList.add(chatItem)
                    chatAdapter.notifyDataSetChanged()
                } else {
                    chatContent.append(it)
                    if (binding.rvChatList.childCount > 0 && chatItemList.last().itemType == ITEM_TYPE_ANSWER) {
                        val view = binding.rvChatList.getChildAt(binding.rvChatList.childCount - 1)
                        val textView = view.findViewById<TextView>(R.id.tv_msg_content)
                        textView.text = chatContent
                    }
                }
            }
        }
    }

    private fun initAdapter() {
        var chatItemBean = ChatItemBean(ITEM_TYPE_GUIDE, getString(R.string.chat_ai_guide))
        chatItemList.add(chatItemBean)
        chatAdapter = ChatAdapter(chatItemList)
        binding.rvChatList.apply {
            adapter = chatAdapter
            layoutManager = LinearLayoutManager(this@ChatNewActivity)
        }
    }

    private fun addLoadingItem() {
        var chatItemBean = ChatItemBean(ITEM_TYPE_LOADING, "loading")
        chatItemList.add(chatItemBean)
        chatAdapter.notifyDataSetChanged()
    }

    private fun addErrorItem(errorInfo: String) {
        var chatItemBean = ChatItemBean(ITEM_TYPE_ERROR, errorInfo)
        chatItemList.add(chatItemBean)
        chatAdapter.notifyDataSetChanged()
    }

    private fun removeLoadingItem() {
        chatItemList.last()?.let {
            if (it.itemType == ITEM_TYPE_LOADING) {
                chatItemList.removeLast()
                chatAdapter.notifyDataSetChanged()
            }
        }
    }

    override fun onPause() {
        super.onPause()
        //存入聊天记录到本地数据库
        recentViewModel.insertHistoryMessage(getHistoryEntity())
    }

    private fun getHistoryEntity(): ChatMessageEntity? {
        val data = getOldChatItemList()
        val firstQuestion =
            data.find { it.type == ChatType.TYPE_QUESTION || it.type == ChatType.TYPE_PHOTO }
                ?: return null
        if (data.find { it.type == ChatType.TYPE_ANSWER && !it.isLoading } == null) return null
        val historyList = data.filter {
            it.type == ChatType.TYPE_QUESTION || (it.type == ChatType.TYPE_ANSWER && !it.isLoading) || it.type == ChatType.TYPE_PHOTO
        }
        var title = ""
        firstQuestion.content?.answer?.let { title = it.substring(0, min(it.length, 27)) }
        val cal = Calendar.getInstance()
        val dataFormat = SimpleDateFormat("MM/dd/yyyy hh:mm a", LanguageUtils.getCurrentLocale())
        val date = dataFormat.format(cal.time)
        return ChatMessageEntity(
            messageTitle = title,
            messageContent = Gson().toJson(historyList),
            date = date
        )
    }


    fun getOldChatItemList(): MutableList<ChatItem> {
        val chatList = mutableListOf<ChatItem>()
        chatItemList.forEach {
            chatList.add(getChatItem(it))
        }
        return chatList
    }

    fun getChatItem(itemBean: ChatItemBean): ChatItem {
        var chatItem: ChatItem
        when (itemBean.itemType) {
            ITEM_TYPE_QUESTION -> {
                chatItem = ChatItem(
                    content = GetAnswerResponse(answer = chatContent.toString()),
                    ChatType.TYPE_QUESTION,
                    false
                )
            }
            ITEM_TYPE_ANSWER -> {
                chatItem = ChatItem(
                    content = GetAnswerResponse(answer = chatContent.toString()),
                    ChatType.TYPE_ANSWER,
                    false
                )
            }
            ITEM_TYPE_GUIDE -> {
                chatItem = ChatItem(
                    content = GetAnswerResponse(answer = chatContent.toString()),
                    ChatType.TYPE_GUIDE,
                    false
                )
            }
            ITEM_TYPE_LOADING -> {
                chatItem = ChatItem(
                    content = GetAnswerResponse(answer = chatContent.toString()),
                    ChatType.TYPE_LOADING,
                    false
                )
            }
            ITEM_TYPE_ERROR -> {
                chatItem = ChatItem(
                    content = GetAnswerResponse(answer = chatContent.toString()),
                    ChatType.TYPE_ERROR,
                    false
                )
            }
            else -> {
                chatItem = ChatItem(
                    content = GetAnswerResponse(answer = chatContent.toString()),
                    ChatType.TYPE_ERROR,
                    false
                )
            }
        }
        return chatItem
    }

}